home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / emac16as.arc / MEMORY.ASM < prev    next >
Assembly Source File  |  1990-04-01  |  12KB  |  623 lines

  1. ;History:409,1
  2. ;Thu Feb 22 23:40:41 1990 make buffer_modified into a bitmap.
  3. ;09-07-88 22:03:44 remove public margin
  4. ;04-07-88 00:08:22 remember to set buffer-modified on xlat_to_mark
  5. ;03-30-88 21:22:37 add xlat_to_mark
  6. ;11-16-87 23:13:40 move calculations involving memsize into buffers.asm
  7. ;11-15-87 00:04:12 call buffer_free.
  8. ;11-14-87 23:09:22 move toptop..botbot out of memory.
  9. ;07-15-87 23:31:17 get rid of dump_bufseg
  10. ;07-13-87 22:53:52 move init_memory to mintprim.asm
  11.  
  12. debugging    equ    0
  13.  
  14.     .xlist
  15.  
  16. HT    equ    09h
  17. LF    equ    0ah
  18. CR    equ    0dh
  19. LINENEW    equ    CR+LF*256    ;the way a newline is stored in memory.
  20.  
  21. bufseg    segment    public
  22.  
  23.     extrn    toptop: word
  24.     extrn    topbot: word
  25.     extrn    bottop: word
  26.     extrn    botbot: word
  27.  
  28.     public    linecount, linesbefore
  29. linecount    dw    ?
  30. linesbefore    dw    ?
  31.  
  32.     public    buffer_modified
  33. buffer_modified    db    ?
  34.  
  35.     extrn    bufseg_size: byte
  36.  
  37. bufseg    ends
  38.  
  39. data    segment    byte public
  40.  
  41. ;the following externs are in 'buffers'
  42.     extrn    textseg: word
  43.  
  44. insert_ds    dw    ?
  45.  
  46. data    ends
  47.  
  48. b_struc    struc
  49. b    db    ?
  50. b_struc    ends
  51.  
  52. w_struc    struc
  53. w    dw    ?
  54. w_struc    ends
  55.  
  56. byte_ptr    label    byte
  57.  
  58. code    segment    byte public
  59. ;all the routines in this segment are entered with ds=data, es=data
  60.     assume    cs:code, ds:data, es:data
  61.  
  62. ;the following externs are in 'marks'
  63.     extrn    init_marks: near
  64.     extrn    get_mark: near
  65.     extrn    adjust_marks_del: near
  66.     extrn    adjust_marks_ins: near
  67.  
  68. ;the following externs are in 'redisp'
  69.     extrn    prevline: near
  70.     extrn    nextline: near
  71.     extrn    compute_one: near
  72.  
  73.  
  74.     public    count_lines
  75. count_lines:
  76.     push    ds
  77.     mov    ds,textseg
  78.     call    count_lines$
  79.     pop    ds
  80.     ret
  81.  
  82.     public    del_to_mark
  83. del_to_mark:
  84.     push    ds
  85.     mov    ds,textseg
  86.     call    del_to_mark$
  87.     pop    ds
  88.     ret
  89.  
  90.  
  91.     public    read_mark
  92. read_mark:
  93.     mov    ds,textseg
  94.     call    read_mark$
  95.     ret
  96.  
  97.  
  98.     public    goto_mark
  99. goto_mark:
  100.     push    ds
  101.     mov    ds,textseg
  102.     call    goto_mark$
  103.     pop    ds
  104.     ret
  105.  
  106.  
  107.     public    xlat_to_mark
  108. xlat_to_mark:
  109.     push    ds
  110.     mov    ds,textseg
  111.     call    xlat_to_mark$
  112.     pop    ds
  113.     ret
  114.  
  115.  
  116.     public    insert_string
  117. insert_string:
  118.     push    ds
  119.     mov    ax,es            ;use data for insert_ds.
  120.     mov    ds,textseg
  121.     call    insert_string$
  122.     pop    ds
  123.     ret
  124.  
  125.  
  126.     public    set_column
  127. set_column:
  128.     push    ds
  129.     mov    ds,textseg
  130.     call    set_column$
  131.     pop    ds
  132.     ret
  133.  
  134.  
  135.     public    set_line
  136. set_line:
  137.     push    ds
  138.     mov    ds,textseg
  139.     call    set_line$
  140.     pop    ds
  141.     ret
  142.  
  143.  
  144.     public    compute_cursor
  145. compute_cursor:
  146. ;exit with dx=column.
  147.     push    ds
  148.     mov    ds,textseg
  149.     call    compute_cursor$
  150.     pop    ds
  151.     ret
  152.  
  153.  
  154.     public    store_buffer_modified
  155. store_buffer_modified:
  156.     push    ds
  157.     mov    ds,textseg
  158.     assume    ds:bufseg
  159.     mov    buffer_modified,al
  160.     pop    ds
  161.     assume    ds:data
  162.     ret
  163.  
  164.  
  165.     public    read_linecount
  166. read_linecount:
  167.     mov    bx,offset linecount
  168.     jmp    short read_variable
  169.     public    read_linesbefore
  170. read_linesbefore:
  171.     mov    bx,offset linesbefore
  172.     jmp    short read_variable
  173.     public    read_buffer_modified
  174. read_buffer_modified:
  175.     mov    bx,offset buffer_modified
  176. read_variable:
  177.     push    ds
  178.     mov    ds,textseg
  179.     assume    ds:bufseg
  180.     mov    ax,bufseg:[bx]
  181.     pop    ds
  182.     assume    ds:data
  183.     ret
  184.  
  185.  
  186.     public    file_size
  187. file_size:
  188. ;exit with ax=size of the current buffer in bytes.
  189.     mov    ds,textseg
  190.     assume    ds:bufseg
  191.     mov    ax,topbot
  192.     sub    ax,toptop
  193.     add    ax,botbot
  194.     sub    ax,bottop
  195.     push    es
  196.     pop    ds
  197.     assume    ds:data
  198.     ret
  199.  
  200.  
  201. code    ends
  202.  
  203. code    segment    byte public
  204. ;all the code in this segment is entered with ds=bufseg, es=data
  205.     assume    cs:code, ds:bufseg, es:data
  206.  
  207. ;the following externs are in 'redisp'
  208.     extrn    paint_window: near
  209.     extrn    trash_line: near
  210.     extrn    window_insert: near
  211.     extrn    window_delete: near
  212.     extrn    up_lines: near
  213.     extrn    down_lines: near
  214.  
  215.     public    init_vars$
  216. init_vars$:
  217.     mov    bx,offset bufseg_size+2
  218.     mov    [bx-02].w,LINENEW
  219.     mov    toptop,bx
  220.     mov    topbot,bx
  221.     mov    bottop,bx
  222.     mov    botbot,bx
  223.     mov    linecount,0
  224.     mov    linesbefore,0
  225.     mov    buffer_modified,0
  226.     ret
  227.  
  228.  
  229.     extrn    buffer_free: near
  230.  
  231.     public    insert_string$
  232. insert_string$:
  233. ;enter with si,cx describing the string to insert, ax=segment of string.
  234. ;exit with cy if there isn't enough room to insert the entire string.
  235.     jcxz    insert_string_1
  236.     mov    es,ax            ;put it where we need it.
  237.     mov    ax,ds
  238.     call    buffer_free
  239.     mov    ss:insert_ds,es        ;remember what it is now.
  240.     push    ss
  241.     pop    es
  242.     jc    insert_string_4        ;no - give error.
  243.     or    buffer_modified,1
  244. insert_string_2:
  245.     push    ds
  246.     mov    ds,insert_ds
  247.     mov    ax,ds:[si]        ;get an entire word, even though we might use only the low byte.
  248.     pop    ds
  249.     cmp    ax,LINENEW    ;newline?
  250.     jne    insert_string_3        ;no.
  251.     cmp    cx,2            ;must be at least two chars left.
  252.     jb    insert_string_3        ;no - can't be newline.
  253.     push    cx
  254.     push    si
  255.     call    inscrlf
  256.     pop    si
  257.     pop    cx
  258.     add    si,2
  259.     dec    cx
  260.     loop    insert_string_2
  261.     jmp    short insert_string_1
  262. insert_string_3:
  263.     push    cx
  264.     push    si
  265.     call    insone
  266.     pop    si
  267.     pop    cx
  268.     inc    si
  269.     loop    insert_string_2
  270. insert_string_1:
  271.     clc
  272.     ret
  273. insert_string_4:
  274.     stc
  275.     ret
  276.  
  277.  
  278. insone:
  279.     cmp    al,CR
  280.     jne    insone_1
  281.     mov    bx,bottop
  282.     cmp    [bx].b,LF
  283.     jne    inschar
  284.     inc    bottop
  285.     jmp    short insone_2
  286. insone_1:
  287.     cmp    al,LF
  288.     jne    inschar
  289.     mov    bx,topbot
  290.     cmp    [bx-01].b,CR
  291.     jne    inschar
  292.     dec    topbot
  293. insone_2:
  294.     mov    ax,1
  295.     call    adjust_marks_del
  296.     call    inscrlf
  297.     ret
  298.  
  299. inschar:
  300. ;insert the character in al at the point.
  301. ;unless there is no room.
  302.     mov    bx,topbot
  303.     cmp    bx,bottop
  304.     jae    inschar_1
  305.     push    ax
  306.     mov    ax,1
  307.     call    adjust_marks_ins
  308.     pop    ax
  309.     mov    di,topbot
  310.     mov    [di],al
  311.     inc    di
  312.     mov    topbot,di
  313.     call    trash_line
  314. inschar_1:
  315.     ret
  316.  
  317.  
  318. inscrlf:
  319.     mov    bx,topbot
  320.     inc    bx
  321.     cmp    bx,bottop
  322.     jae    inscrlf_3
  323.  
  324.     mov    ax,2
  325.     call    adjust_marks_ins
  326.  
  327.     mov    di,topbot
  328.     mov    [di].w,LINENEW
  329.     add    di,2
  330.     mov    topbot,di
  331.  
  332.     inc    linesbefore
  333.     inc    linecount
  334.  
  335.     call    window_insert        ;say that we inserted a line here.
  336.  
  337. inscrlf_3:
  338.     ret
  339.  
  340.  
  341. del_to_mark$:
  342.     call    get_mark
  343.     jcxz    del_to_mark_4_j_1
  344.     jc    del_to_mark_2        ;go if point>mark
  345.     push    bottop
  346.     call    move_point_backward    ;swap point and mark (sort of).
  347.     pop    si            ;pushed as bottop.
  348. del_to_mark_2:
  349.     or    buffer_modified,1
  350.     mov    di,toptop        ;are we at the beginning of the file?
  351.     cmp    di,topbot
  352.     jne    del_to_mark_1        ;no
  353.     cmp    si,botbot        ;deleting to the end of the file?
  354.     jne    del_to_mark_1        ;no
  355.     mov    ax,si
  356.     sub    ax,bottop        ;compute the number of chars deleted.
  357.     mov    bottop,si        ;no characters left.
  358.     call    adjust_marks_del
  359.     mov    linecount,0        ;no lines left.
  360.     call    paint_window        ;trash the window.
  361. del_to_mark_4_j_1:
  362.     jmp    short del_to_mark_4    ;now exit.
  363. del_to_mark_1:
  364.     mov    bp,si            ;save the char that we delete to.
  365.     mov    ax,si            ;compute the number of chars.
  366.     sub    ax,bottop
  367.     call    adjust_marks_del    ;fix up the marks first.
  368.     mov    si,bottop        ;get the -> first char to delete.
  369. del_to_mark_3:
  370.     cmp    [si].w,LINENEW        ;a newline?
  371.     jne    del1_1            ;no - just skip this char.
  372.     inc    si            ;extra inc to skip past the CR.
  373.     dec    linecount        ;one less line.
  374.     call    window_delete        ;fix up the window.
  375. del1_1:
  376.     inc    si
  377.     cmp    bp,si
  378.     jne    del_to_mark_3
  379.     mov    bottop,si
  380.     call    trash_line
  381. ;now check for a newly created newline.
  382.     mov    bx,topbot
  383.     cmp    [bx-1].b,CR
  384.     jne    del_to_mark_4
  385.     mov    bx,bottop
  386.     cmp    [bx].b,LF
  387.     jne    del_to_mark_4
  388. ;get rid of the LF and CR seperately so that any mark that points to either
  389. ;  one will point to the newline.
  390.     inc    bottop            ;get rid of the LF
  391.     mov    ax,1
  392.     call    adjust_marks_del
  393.     dec    topbot            ;get rid of the CR
  394.     mov    ax,1
  395.     call    adjust_marks_del
  396.     call    inscrlf            ;now insert a newline.
  397. del_to_mark_4:
  398.     ret
  399.  
  400.  
  401. xlat_to_mark$:
  402. ;enter with al =mark, bx,dx ->translate string.
  403.     push    bx
  404.     push    dx
  405.     call    read_mark$
  406.     pop    dx
  407.     pop    bx
  408.     jcxz    xlat_to_mark_2        ;quit if no chars in the region.
  409.     or    buffer_modified,1
  410. xlat_to_mark_1:
  411.     cmp    word ptr [si],LINENEW    ;is this a newline?
  412.     jne    xlat_to_mark_3
  413.     add    si,2            ;yes - skip it.
  414.     dec    cx
  415.     jmp    short xlat_to_mark_4
  416. xlat_to_mark_3:
  417.     lodsb                ;translate the character.
  418.     cmp    al,dl            ;is this character in the translate char?
  419.     jae    xlat_to_mark_4        ;yes - it is.
  420.     xlat    es:[bx]
  421.     mov    [si-1],al
  422. xlat_to_mark_4:
  423.     loop    xlat_to_mark_1
  424. xlat_to_mark_2:
  425.     call    paint_window        ;trash the window.
  426.     ret
  427.  
  428.  
  429.     public    goto_mark$
  430. goto_mark$:
  431.     call    get_mark
  432.     jcxz    goto_mark_1
  433.     jnc    goto_mark_2
  434.     call    move_point_forward
  435.     jmp    short goto_mark_1
  436. goto_mark_2:
  437.     call    move_point_backward
  438. goto_mark_1:
  439.     ret
  440.  
  441.  
  442.     public    read_mark$
  443. read_mark$:
  444.     call    get_mark
  445.     jnc    read_mark_1
  446.     mov    si,bottop
  447. read_mark_1:
  448.     ret
  449.  
  450.  
  451. move_point_backward:
  452.     mov    si,topbot
  453.     mov    di,bottop
  454.     push    es
  455.     push    ds
  456.     pop    es
  457.     std
  458.     dec    si
  459.     dec    di
  460.     push    cx
  461.     rep    movsb
  462.     pop    cx
  463.     inc    si
  464.     inc    di
  465.     cld
  466.     pop    es
  467.     mov    topbot,si
  468.     mov    bottop,di
  469.     call    count_lines$
  470.     sub    linesbefore,bx
  471.     call    up_lines
  472.     ret
  473.  
  474.  
  475. move_point_forward:
  476.     mov    si,bottop
  477.     mov    di,topbot
  478.     push    di
  479.     push    cx
  480.     push    es
  481.     push    ds
  482.     pop    es
  483.     rep    movsb
  484.     pop    es
  485.     mov    bottop,si
  486.     mov    topbot,di
  487.     pop    cx
  488.     pop    di
  489.     call    count_lines$
  490.     add    linesbefore,bx
  491.     call    down_lines
  492.     ret
  493.  
  494.  
  495. count_lines$:
  496. ;count the number of newlines contained in the text described by ds:di,cx.
  497.     push    es
  498.     push    ds
  499.     pop    es
  500.     mov    bx,0
  501. count_lines_1:
  502.     mov    al,CR
  503.     repnz    scasb
  504.     jcxz    count_lines_2
  505.     cmp    [di].b,LF
  506.     jne    count_lines_1
  507.     inc    bx
  508.     jmp    count_lines_1
  509. count_lines_2:
  510.     pop    es
  511.     ret
  512.  
  513.  
  514.     public    set_line$
  515. set_line$:
  516. ;given a line number in ax, move to that line.
  517.     dec    ax            ;linesbefore is zero based.
  518.     or    ax,ax            ;if negative, use zero.
  519.     jns    set_line_0
  520.     xor    ax,ax
  521. set_line_0:
  522.     sub    ax,linesbefore
  523.     je    set_line_1        ;go if we're already on that line.
  524.     jb    set_line_2        ;go if we're after that line.
  525.     mov    cx,ax
  526.     mov    si,bottop
  527. set_line_4:
  528.     call    nextline
  529.     loopne    set_line_4
  530.     mov    cx,si            ;compute the number of characters.
  531.     sub    cx,bottop
  532.     call    move_point_forward
  533.     jmp    short set_line_1
  534. set_line_2:
  535.     neg    ax            ;ax is the number of lines to move.
  536.     mov    cx,ax
  537.     mov    si,topbot
  538.     cmp    [si-2].w,LINENEW    ;are we at the beginning of a line?
  539.     je    set_line_3        ;yes.
  540.     call    prevline        ;no, go to the beginning of the line.
  541. set_line_3:
  542.     call    prevline
  543.     loopne    set_line_3
  544.     mov    cx,topbot        ;compute the number of characters.
  545.     sub    cx,si
  546.     call    move_point_backward
  547. set_line_1:
  548.     ret
  549.  
  550.  
  551. set_column$:
  552. ;given a column number in ax, move to that column.
  553.     mov    bx,ax        ;save the column number in bx.
  554.     dec    bx        ;columns are zero based.
  555.     mov    si,topbot
  556.     jmp    short set_column$_2
  557. set_column$_1:
  558.     dec    si
  559. set_column$_2:
  560.     cmp    [si-2].w,LINENEW
  561.     jne    set_column$_1
  562. ;now move over to the point, counting the size of characters on the way.
  563.     mov    dx,0
  564.     mov    cx,topbot
  565.     sub    cx,si
  566.     jcxz    set_column$_3
  567. set_column$_4:
  568.     cmp    dx,bx        ;are we at or past the desired column?
  569.     jae    set_column$_6    ;yes - move the point backward.
  570.     lodsb
  571.     call    compute_one
  572.     loop    set_column$_4
  573. set_column$_3:
  574. ;the desired column is somewhere after the point.
  575.     mov    si,bottop
  576. set_column$_7:
  577.     cmp    dx,bx        ;are we at or past the desired column?
  578.     jae    set_column$_5    ;yes - go to the column.
  579.     cmp    si,botbot    ;did we hit eof?
  580.     je    set_column$_5    ;yes - this is as close as we can get.
  581.     cmp    [si].w,LINENEW    ;are we at the end of the line?
  582.     je    set_column$_5    ;yes - this is as close as we can get.
  583.     lodsb            ;compute the next character.
  584.     call    compute_one
  585.     jmp    set_column$_7
  586. set_column$_5:
  587.     mov    cx,si
  588.     sub    cx,bottop
  589.     call    move_point_forward
  590.     ret
  591. set_column$_6:
  592.     call    move_point_backward
  593.     ret
  594.  
  595.  
  596.     public    compute_cursor$
  597. compute_cursor$:
  598. ;return the column in dx.
  599. ;find the beginning of this line.
  600.     mov    si,topbot
  601.     jmp    short compute_cursor$_2
  602. compute_cursor$_1:
  603.     dec    si
  604. compute_cursor$_2:
  605.     cmp    [si-2].w,LINENEW
  606.     jne    compute_cursor$_1
  607. ;now move over to the point, counting the size of characters on the way.
  608.     mov    dx,0
  609.     mov    cx,topbot
  610.     sub    cx,si
  611.     jcxz    compute_cursor$_3
  612. compute_cursor$_4:
  613.     lodsb
  614.     call    compute_one
  615.     loop    compute_cursor$_4
  616. compute_cursor$_3:
  617.     ret
  618.  
  619.  
  620. code    ends
  621.  
  622.     end
  623.